use std::sync::Arc;

use axum::{extract::State, Json};
use validator::Validate;

use crate::{
    form,
    handler::{get_conn, log_error, AffResponse, Response},
    jwt::AdminClaimsData,
    middleware::RequiredAuth,
    service, utils, AppState, Error, Result,
};

pub async fn change_password(
    State(state): State<Arc<AppState>>,
    RequiredAuth(claims): RequiredAuth<AdminClaimsData>,
    Json(frm): Json<form::profile::ChangePassword>,
) -> Result<Json<Response<AffResponse>>> {
    let handler_name = "admin/profile/change_password";

    frm.validate()
        .map_err(Error::from)
        .map_err(log_error(handler_name))?;

    if frm.password == frm.new_password {
        return Err(Error::invalid_parameter("玩呢？新密码和现用密码相同"));
    }

    if frm.new_password != frm.re_password {
        return Err(Error::invalid_parameter("两次输入的密码不一致"));
    }

    let password = utils::password::hash(&frm.new_password).map_err(log_error(handler_name))?;

    let pool = get_conn(&state);

    let rows =
        service::user::change_password(&pool, &claims.data.id, &password, Some(&frm.password))
            .await
            .map_err(log_error(handler_name))?;

    Ok(Response::ok(AffResponse { rows }).to_json())
}
